package controller

import (
	"errors"
	"math/rand"
	"net/http"
	"path/filepath"

	"time"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

type Result struct {
	Success bool        `json:"success"`
	Data    interface{} `json:"data"`
	Message string      `json:"message"`
}

// 请求成功
func Success(c *gin.Context, data interface{}) {

	c.JSON(http.StatusOK, Result{
		Success: true,
		Data:    data,
		Message: "请求成功",
	})
}

// 请求失败
func Fail(c *gin.Context, message string) {
	c.JSON(http.StatusOK, Result{
		Success: false,
		Data:    "",
		Message: message,
	})
}

// 搜索时间格式化
func SearchTimeFormat(inTime []string) []string {
	var returnStrArr []string

	shanghai, _ := time.LoadLocation("Asia/Shanghai")

	for _, v := range inTime {
		receivedTime, _ := time.Parse(time.RFC3339, v)
		shanghaiTime := receivedTime.In(shanghai)

		// 格式化上海时区的时间
		shanghaiTimeFormatted := shanghaiTime.Format("2006-01-02 15:04:05")
		returnStrArr = append(returnStrArr, shanghaiTimeFormatted)
	}

	return returnStrArr
}

func WhereStructure(requestDataMap map[string]interface{}) (map[string]interface{}, int, int) {
	// 创建一个 map 用于存储条件
	where := make(map[string]interface{})
	// 使用反射遍历 requestDataMap 并填充 where map
	for key, value := range requestDataMap {
		if key == "page" || key == "limit" {
			continue
		}
		switch v := value.(type) {
		case string: //string 模糊搜索
			if v != "" {
				where[key+" like ?"] = "%%" + value.(string) + "%%"
			}
		case []interface{}: //字符串 时间搜索
			// 首先将 value 转换为 []interface{} 类型
			if v, ok := value.([]interface{}); ok {
				// 检查切片长度是否大于 0
				if len(v) > 0 {
					// 将切片中的元素转换为字符串并放入 where map 中
					if str, ok := v[0].(string); ok {
						where[key+" >= ?"] = str
					}
					if len(v) > 1 {
						if str, ok := v[1].(string); ok {
							where[key+" <= ?"] = str
						}
					}
				}
			}
		case float64: //int 数字直接查询
			if v != -1 {
				where[key] = value
			}
		}
	}

	// 声明 page 和 pageSize 的默认值
	var page, pageSize int = 1, 10 // 默认值：page 为 1，pageSize 为 10

	// 检查 requestDataMap 中是否存在 "page" 键
	if val, ok := requestDataMap["page"]; ok {
		// 将 "page" 键的值转换为 int 类型
		if pageFloat, ok := val.(float64); ok {
			page = int(pageFloat)
		}
	}

	// 检查 requestDataMap 中是否存在 "limit" 键
	if val, ok := requestDataMap["limit"]; ok {
		// 将 "limit" 键的值转换为 int 类型
		if limitFloat, ok := val.(float64); ok {
			pageSize = int(limitFloat)
		}
	}
	return where, page, pageSize
}

func GetFirstDayOfMonth(t time.Time) time.Time {
	year, month, _ := t.Date()
	return time.Date(year, month, 1, 0, 0, 0, 0, t.Location())
}

func GetLastDayOfMonth(t time.Time) time.Time {
	nextMonth := t.AddDate(0, 1, 0)
	return GetFirstDayOfMonth(nextMonth).Add(-time.Second)
}

func GetFirstDayOfYear(t time.Time) time.Time {
	year, _, _ := t.Date()
	return time.Date(year, time.January, 1, 0, 0, 0, 0, t.Location())
}

func GetLastDayOfYear(t time.Time) time.Time {
	year := t.Year()
	return time.Date(year, time.December, 31, 23, 59, 59, 999999999, t.Location())
}

// 获取上传文件
func GetUploadFile(c *gin.Context, fileName string) (string, error) {
	file, err := c.FormFile(fileName + "[0][raw]")
	if err != nil {
		return "", errors.New("上传文件失败")
	}

	// 生成随机文件名
	randomFileName := GenerateRandomFileName(file.Filename)

	// 将文件保存到指定路径
	err = c.SaveUploadedFile(file, "./uploads/"+randomFileName)
	if err != nil {
		return "", errors.New("保存文件失败")
	}

	return randomFileName, nil
}

// 生成随机文件名
func GenerateRandomFileName(filename string) string {
	ext := filepath.Ext(filename)
	randomID := uuid.New().String()
	return randomID + ext
}

// 随机字符串
func GenerateString(length int) string {

	rand.Seed(time.Now().UnixNano())

	// 定义一个包含所有可能字符的字符串
	chars := "abcdefghijklmnopqrstuvwxyz"

	// 创建一个字节切片用于存储生成的随机字符串
	randomString := make([]byte, length)

	// 从字符集合中随机选择4个字符
	for i := range randomString {
		randomString[i] = chars[rand.Intn(len(chars))]
	}

	// 将字节切片转换为字符串并输出
	return string(randomString)
}

func IntToBool(value int) bool {
	if value == 1 {
		return true
	}
	return false
}

func BoolToInt(value bool) int {
	if value {
		return 1
	}
	return 0
}
